package edu.boun.g4.coursity.service;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import edu.boun.g4.coursity.domain.Course;
import edu.boun.g4.coursity.domain.CoursityUser;

/**
 * 
 * @author mertusta
 * @author sebnemarslan
 */
@Service("userService")
@Transactional
public class UserService {

	protected static Logger logger = Logger.getLogger("service");

	@Resource(name = "sessionFactory")
	private SessionFactory sessionFactory;

	/**
	 * Retrieves all persons
	 * 
	 * @return a list of persons
	 */
	@SuppressWarnings("unchecked")
	public List<CoursityUser> getAll() {
		logger.debug("Retrieving all users");

		// Retrieve session from Hibernate
		Session session = sessionFactory.getCurrentSession();

		// Create a Hibernate query (HQL)
		Query query = session.createQuery("FROM  CoursityUser");

		// Retrieve all
		return query.list();
	}

	/**
	 * Retrieves all followings of a user
	 */
	public List<CoursityUser> getAllFollowing(Integer personId) {
		logger.debug("Retrieving all followings of the user");

		// Retrieve session from Hibernate
		Session session = sessionFactory.getCurrentSession();

		// Create a Hibernate query (HQL)
		Query query = session
				.createQuery("FROM CoursityUser as p LEFT JOIN FETCH  p.following WHERE p.id="
						+ personId);

		CoursityUser coursityUser = (CoursityUser) query.uniqueResult();

		// Retrieve all
		return new ArrayList<CoursityUser>(coursityUser.getFollowing());
	}
	
	
	/**
	 * Retrieves a single user
	 */
	public CoursityUser get(Integer id) {
		// Retrieve session from Hibernate
		Session session = sessionFactory.getCurrentSession();

		// Retrieve existing person first
		CoursityUser coursityUser = (CoursityUser) session.get(
				CoursityUser.class, id);

		return coursityUser;
	}
	public CoursityUser getByMail(String email) {
		// Retrieve session from Hibernate
		Session session = sessionFactory.getCurrentSession();

		// Retrieve existing person first
		Query query = session
				.createQuery("FROM CoursityUser as p WHERE p.email='"
						+ email+"'");

		CoursityUser coursityUser = (CoursityUser) query.uniqueResult();

		return coursityUser;
	}

	
	/**
	 * Retrieves user of a user course rating
	 */
	public Integer getByRating(Integer ratingId) {
		logger.debug("Retrieving course by rating");
		// Retrieve session from Hibernate
		Session session = sessionFactory.getCurrentSession();

		// Create a Hibernate query (HQL)
		Query query = session
				.createQuery("Select p.id FROM CoursityUser as p LEFT JOIN FETCH p.ratings WHERE p.id="
						+ ratingId);

		// Retrieve all
		Integer coursityUser = (Integer) query.uniqueResult();

		// Retrieve all
		return coursityUser;
	}
	
	/**
	 * Adds a new user
	 */
	public void add(CoursityUser coursityUser) {
		logger.debug("Adding new user");

		// Retrieve session from Hibernate
		Session session = sessionFactory.getCurrentSession();

		// Persists to db
		session.save(coursityUser);
		session.refresh(coursityUser);
	}

	/**
	 * Deletes an existing user
	 * 
	 * @param id
	 *            the id of the existing user�
	 */
	public void delete(Integer id) {
		logger.debug("Deleting existing user");

		// Retrieve session from Hibernate
		Session session = sessionFactory.getCurrentSession();

		// Retrieve existing user first
		CoursityUser coursityUser = (CoursityUser) session.get(
				CoursityUser.class, id);

		// Delete
		session.delete(coursityUser);
	}

	/**
	 * Edits an existing user
	 */
	public void edit(CoursityUser coursityUser) {
		logger.debug("Editing existing user");

		// Retrieve session from Hibernate
		Session session = sessionFactory.getCurrentSession();

		// Retrieve existing person via id
		CoursityUser existingUser = (CoursityUser) session.get(
				CoursityUser.class, coursityUser.getId());

		// Assign updated values to this person
		existingUser.setName(coursityUser.getName());
		existingUser.setUsername(coursityUser.getUsername());
		existingUser.setEmail(coursityUser.getEmail());
		existingUser.setPassword(coursityUser.getPassword());
		existingUser.setActive(coursityUser.isActive());

		// Save updates
		session.save(existingUser);
	}
}
